package com.android.datn.services;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;

import org.apache.http.NameValuePair;
import org.json.JSONObject;

import com.android.datn.MyApplication;
import com.android.datn.activities.ADetailMusic;
import com.android.datn.activities.ASongOfFavorite;
import com.android.datn.adapter.TracksAdapter.VoteAsync;
import com.android.datn.helper.DBBinding;
import com.android.datn.helper.JSonCustomException;
import com.android.datn.objects.Track;
import com.android.datn.utils.CommonUtil;

import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.app.Activity;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnBufferingUpdateListener;
import android.media.MediaPlayer.OnCompletionListener;
import android.media.MediaPlayer.OnErrorListener;
import android.media.MediaPlayer.OnInfoListener;
import android.media.MediaPlayer.OnPreparedListener;
import android.media.MediaPlayer.OnSeekCompleteListener;
import android.os.AsyncTask;
import android.os.Binder;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.util.Log;
import android.widget.Toast;

@SuppressLint("NewApi")
public class AudioPlayer extends Service implements OnCompletionListener,
		OnPreparedListener, OnErrorListener, OnSeekCompleteListener,
		OnInfoListener, OnBufferingUpdateListener {
	public static final String INTENT_BASE_NAME = "com.augusto.mymediaplayer.AudioPlayer";
	private int mCurrentPosition = 0;
	private final String TAG = "AudioPlayer";
	private MediaPlayer mediaPlayer;
	private boolean paused = false;
	private AudioPlayerBroadcastReceiver broadcastReceiver = new AudioPlayerBroadcastReceiver();
	private Handler handler = new Handler();
	private Thread mThreadMusic;
	private int mPercentCurrentTrack = 0;
	private Track mCurrentTrack;
	private boolean mIsRepared = false;

	public class AudioPlayerBinder extends Binder {
		public AudioPlayer getService() {
			Log.v(TAG, "AudioPlayerBinder: getService() called");
			return AudioPlayer.this;
		}
	}

	private final IBinder audioPlayerBinder = new AudioPlayerBinder();

	@Override
	public IBinder onBind(Intent intent) {
		Log.v(TAG, "AudioPlayer: onBind() called");
		return audioPlayerBinder;
	}

	@Override
	public void onCreate() {
		Log.v(TAG, "AudioPlayer: onCreate() called");
		IntentFilter intentFilter = new IntentFilter();
		intentFilter.addAction(DBBinding.INTENT_PLAY_ID);
		registerReceiver(broadcastReceiver, intentFilter);
		mediaPlayer = new MediaPlayer();
		mediaPlayer.setOnCompletionListener(this);
		mediaPlayer.setOnErrorListener(this);
		mediaPlayer.setOnPreparedListener(this);
		mediaPlayer.setOnBufferingUpdateListener(this);
		mediaPlayer.setOnSeekCompleteListener(this);
		mediaPlayer.setOnInfoListener(this);
	}

	@Override
	public void onStart(Intent intent, int startId) {
		Log.i(TAG, "AudioPlayer: onStart() called, instance=" + this.hashCode());
	}

	@Override
	public void onDestroy() {
		Log.i(TAG, "AudioPlayer: onDestroy() called");
		release();
	}

	@Override
	public void onLowMemory() {
		NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
		@SuppressWarnings("deprecation")
		Notification notification = new Notification(
				android.R.drawable.ic_dialog_alert, "closing low memory",
				System.currentTimeMillis());
		notificationManager.notify(1, notification);
		stopSelf();
	}

	public void onCompletion(MediaPlayer _mediaPlayer) {
		release();
		Log.d("Complete", "Ok");
		if (mCurrentPosition < MyApplication.ArrayTrack.size() - 1) {
			MyApplication.ArrayTrack.get(mCurrentPosition).setListening(false);
			nextTrack();
		} else {
			// mCurrentTrack = null;
		}

	}

	private void release() {
		if (mediaPlayer == null) {
			return;
		}

		if (mediaPlayer.isPlaying()) {
			mediaPlayer.stop();
		}
		// mediaPlayer.release();
		// mediaPlayer = null;
	}

	@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
	public void play(int position) {
		mIsRepared = false;
		for (int i = 0; i < MyApplication.ArrayTrack.size(); i++) {
			MyApplication.ArrayTrack.get(i).setListening(false);
		}
		if (mCurrentPosition < MyApplication.ArrayTrack.size())
			MyApplication.ArrayTrack.get(mCurrentPosition).setListening(false);
		mCurrentPosition = position;
		if (MyApplication.ArrayTrack.size() == 0) {
			return;
		}
		if (mCurrentPosition < MyApplication.ArrayTrack.size()) {
			MyApplication.ArrayTrack.get(mCurrentPosition).setListening(true);
		}

		if (mThreadMusic != null) {
			mThreadMusic = null;

		}

		mThreadMusic = new Thread(run1);
		mThreadMusic.start();
	}

	private Runnable run1 = new Runnable() {
		public void run() {
			/*Track track = new Track(MyApplication.ArrayTrack.get(
					mCurrentPosition).getId());
			track.setTitle(MyApplication.ArrayTrack.get(mCurrentPosition)
					.getTitle());
			track.setArtist(MyApplication.ArrayTrack.get(mCurrentPosition)
					.getArtist());
			track.setDuration(MyApplication.ArrayTrack.get(mCurrentPosition)
					.getDuration());
			track.setTrackNumber(MyApplication.ArrayTrack.get(mCurrentPosition)
					.getTrackNumber());
			track.setLink(MyApplication.ArrayTrack.get(mCurrentPosition)
					.getLink());
			track.setCode(MyApplication.ArrayTrack.get(mCurrentPosition)
					.getCode());
			track.setCreated(MyApplication.ArrayTrack.get(mCurrentPosition)
					.getCreated());
			track.setDescription(MyApplication.ArrayTrack.get(mCurrentPosition)
					.getDescription());
			track.setIdCategory(MyApplication.ArrayTrack.get(mCurrentPosition)
					.getIdCategory());
			track.setListen(MyApplication.ArrayTrack.get(mCurrentPosition)
					.getListen());
			track.setListening(MyApplication.ArrayTrack.get(mCurrentPosition)
					.isListening());
			track.setPercentCurrent(MyApplication.ArrayTrack.get(
					mCurrentPosition).getPercentCurrent());
			track.setPrepared(MyApplication.ArrayTrack.get(mCurrentPosition)
					.isPrepared());
			track.setRank(MyApplication.ArrayTrack.get(mCurrentPosition)
					.getRank());
			track.setType(MyApplication.ArrayTrack.get(mCurrentPosition)
					.getType());
			track.setTypes(MyApplication.ArrayTrack.get(mCurrentPosition)
					.getTypes());
			track.setVote(MyApplication.ArrayTrack.get(mCurrentPosition)
					.getVote());
			track.setFavorite(MyApplication.ArrayTrack.get(mCurrentPosition)
					.isFavorite());*/
			mCurrentTrack = MyApplication.ArrayTrack.get(
					mCurrentPosition);
			playListUpdated();
			mCurrentTrack.setCurrentPosition(0);
			mCurrentTrack.setDuration(0);
			mCurrentTrack.setPercentCurrent(0);
			mCurrentTrack.setPrepared(false);
			mPercentCurrentTrack = 0;
			try {

				mediaPlayer.reset();
				mediaPlayer.setDataSource(mCurrentTrack.getLink());
				// mediaPlayer.prepareAsync();
				mediaPlayer.prepare();
				mediaPlayer.start();
				// Toast.makeText(getBaseContext(),
				// Formatter.formatTimeFromMillis(mediaPlayer.getDuration()),
				// Toast.LENGTH_SHORT).show();
				// mediaPlayer.setOnCompletionListener(this);

			} catch (IOException ioe) {
				/*
				 * Log.e(TAG, "error trying to play " + track, ioe); String
				 * message = "error trying to play track: " + track +
				 * ".\nError: " + ioe.getMessage();
				 */
			}
		}
	};

	private void playListUpdated() {
		Intent bindServiceDetail = new Intent(DBBinding.SERVICE_DETAIL);
		AudioPlayer.this.sendBroadcast(bindServiceDetail);
		Intent bindServiceSongOfAlBum = new Intent(
				DBBinding.SERVICE_SONG_OF_ALBUM);
		AudioPlayer.this.sendBroadcast(bindServiceSongOfAlBum);
		Intent bindServiceAlbumItem = new Intent(DBBinding.SERVICE_ALBUM_ITEM);
		AudioPlayer.this.sendBroadcast(bindServiceAlbumItem);
		Intent bindServiceFavorite = new Intent(
				DBBinding.SERVICE_SONG_OF_FAVORITE);
		AudioPlayer.this.sendBroadcast(bindServiceFavorite);
		Intent bindServiceTop = new Intent(DBBinding.SERVICE_SONG_TOP);
		AudioPlayer.this.sendBroadcast(bindServiceTop);
		if(mCurrentTrack.isFavorite()){
			Intent bindServiceFavorite1 = new Intent(
					DBBinding.SERVICE_SONG_OF_FAVORITE_LISTEN);
			Bundle bundle = new Bundle();
			bundle.putSerializable(DBBinding.ALBUM, mCurrentTrack);
			bindServiceFavorite1.putExtra(DBBinding.BUNDLEALBUM, bundle);
			AudioPlayer.this.sendBroadcast(bindServiceFavorite1);
			
			//
			Intent bindServiceFavoriteDetail = new Intent(
					DBBinding.SERVICE_DETAIL_LISTEN_OFFLINE);
			Bundle bundle1 = new Bundle();
			bundle1.putSerializable(DBBinding.ALBUM, mCurrentTrack);
			bindServiceFavoriteDetail.putExtra(DBBinding.BUNDLEALBUM, bundle);
			AudioPlayer.this.sendBroadcast(bindServiceFavoriteDetail);
		}
	}

	public void nextTrack() {
		if (MyApplication.ArrayTrack.size() - 1 > mCurrentPosition) {
			MyApplication.ArrayTrack.get(mCurrentPosition).setListening(false);
			mCurrentPosition++;
			play(mCurrentPosition);
		}
	}

	public void previousTrack() {
		if (mCurrentPosition > 0) {
			MyApplication.ArrayTrack.get(mCurrentPosition).setListening(false);
			mCurrentPosition--;
			play(mCurrentPosition);
		}
	}

	public void stop() {
		release();
	}

	public boolean isPlaying() {
		if (MyApplication.ArrayTrack.isEmpty() || mediaPlayer == null) {
			return false;
		}
		return mediaPlayer.isPlaying();
	}

	public void pause() {
		if (mediaPlayer != null) {
			mediaPlayer.pause();
			paused = true;
		}
	}

	public void play() {
		if (mediaPlayer != null) {
			mediaPlayer.start();
			paused = false;
		}
	}

	public Track getCurrentTrack() {
		if (mCurrentTrack == null) {
			return null;
		} else {
			if (mIsRepared && mediaPlayer.isPlaying()) {
				mCurrentTrack.setDuration(mediaPlayer.getDuration());
				mCurrentTrack.setCurrentPosition(mediaPlayer
						.getCurrentPosition());
				mCurrentTrack.setPercentCurrent(mPercentCurrentTrack);
			}
		}
		return mCurrentTrack;
	}

	public int elapsed() {
		if (mediaPlayer == null) {
			return 0;
		}
		return mediaPlayer.getCurrentPosition();
	}

	public void seek(int timeInMillis) {
		if (mediaPlayer != null && mediaPlayer.isPlaying()) {
			mediaPlayer.seekTo(timeInMillis);
		}
	}

	private class AudioPlayerBroadcastReceiver extends BroadcastReceiver {

		@Override
		public void onReceive(Context context, Intent intent) {
			String action = intent.getAction();
			int id = intent.getIntExtra("id", -1);
			if (DBBinding.INTENT_PLAY_ID.equals(action)) {
				play(id);
			} else {
				Log.d(TAG, "Action not recognized: " + action);
			}
		}

	}

	@Override
	public void onBufferingUpdate(MediaPlayer mp, int percent) {
		mPercentCurrentTrack = percent;
		mCurrentTrack.setPrepared(true);
	}

	@Override
	public boolean onInfo(MediaPlayer mp, int what, int extra) {
		return false;
	}

	@Override
	public void onSeekComplete(MediaPlayer mp) {
	}

	@Override
	public boolean onError(MediaPlayer mp, int what, int extra) {
		return false;
	}

	@Override
	public void onPrepared(MediaPlayer mp) {
		mCurrentTrack.setPrepared(true);
		mPercentCurrentTrack = 0;
		mIsRepared = true;
		if (!mCurrentTrack.isFavorite() && mCurrentTrack.getType() == 1) {
			List<NameValuePair> list = new ArrayList<NameValuePair>();
			NameValuePair value = new org.apache.http.message.BasicNameValuePair(
					"id", String.valueOf(mCurrentTrack.getId()));
			list.add(value);
			value = new org.apache.http.message.BasicNameValuePair("post",
					"update");
			list.add(value);
			ListenAsync ws = new ListenAsync();
			ws.execute(
					"http://www.mrmai.info/products/musicrank/apis/1.0/do_listen",
					list);
		}
	}

	public class ListenAsync extends AsyncTask<Object, Void, Object> {
		@SuppressWarnings("unchecked")
		@Override
		protected Object doInBackground(Object... params) {
			// TODO Auto-generated method stub
			JSONObject json = null;
			try {
				json = CommonUtil.getJSONFromUrlParams((String) params[0],
						(List<NameValuePair>) params[1]);
			} catch (JSonCustomException e) {
				return e.getMessage();
			} catch (UnsupportedEncodingException e) {
				return e.getMessage();
			} catch (IOException e) {
				return e.getMessage();
			}
			return json;
		}

		@Override
		protected void onPreExecute() {
			// TODO Auto-generated method stub
			super.onPreExecute();
		}

		@Override
		protected void onPostExecute(Object result) {
			if (result instanceof JSONObject) {
				if (result != null) {
					Intent bindServiceDetail = new Intent(
							DBBinding.SERVICE_DETAIL_LISTEN);
					Bundle bundle = new Bundle();
					bundle.putSerializable(DBBinding.ALBUM, mCurrentTrack);
					bindServiceDetail.putExtra(DBBinding.BUNDLEALBUM, bundle);
					AudioPlayer.this.sendBroadcast(bindServiceDetail);

					Intent bindServiceItemAlbum = new Intent(
							DBBinding.SERVICE_ALBUM_ITEM_LISTENT);
					Bundle bundle1 = new Bundle();
					bundle1.putSerializable(DBBinding.ALBUM, mCurrentTrack);
					bindServiceItemAlbum.putExtra(DBBinding.BUNDLEALBUM,
							bundle1);
					AudioPlayer.this.sendBroadcast(bindServiceItemAlbum);
				}
			} else {
				CommonUtil.dialogNotify(getBaseContext(), (((String) result)),
						"Music Online");
			}
		}
	}
}
